home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / CONTRIB / RINGS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.8 KB  |  280 lines

  1. /* rings.c
  2.  *
  3.  * To compile: cc -o rings rings.c -lGL -lGLU -lX11 -lglut -lXmu -lm
  4.  *
  5.  * Usage: rings
  6.  *
  7.  * Homework 4, Part 1: perspective, hierarchical coords, moving eye pos.
  8.  *
  9.  * Do a slow zoom on a bunch of rings (ala Superman III?)
  10.  *
  11.  * Philip Winston - 2/21/95
  12.  * pwinston@hmc.edu
  13.  * http://www.cs.hmc.edu/people/pwinston
  14.  *
  15.  */
  16.  
  17. #include <GL/glut.h>
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <math.h>
  22.  
  23. /* Some <math.h> files do not define M_PI... */
  24. #ifndef M_PI
  25. #define M_PI 3.14159265358979323846
  26. #endif
  27.  
  28. typedef enum {MENU_STARTOVER, MENU_ZOOM_OUT, MENU_STOP_RINGS, MENU_STOP_FADE, 
  29.               MENU_START_RINGS, MENU_START_FADE, MENU_QUIT} MenuChoices;
  30.  
  31. typedef enum {NOTALLOWED, CONE, TORUS, INNERMAT, OUTTERMAT} DisplayLists;
  32.  
  33. #define STEPS 30
  34.  
  35. int Fade = 1;   /* Start moving out */
  36.  
  37. float Axis = 0, AxisInc = (2.0 * M_PI / STEPS);
  38.  
  39. GLfloat InnerRad, OutterRad, Tilt, Trans, TransCone, Dist;
  40.  
  41.   /* mainly computes the translation amount as a function of the
  42.      tilt angle and torus radii */
  43. void myInit(void)
  44. {
  45.   float sinoftilt;
  46.  
  47.   InnerRad = 0.70;
  48.   OutterRad = 5.0;
  49.   Tilt = 15;
  50.   Dist = 10;
  51.  
  52.   sinoftilt = sin(Tilt * M_PI*2/360);
  53.  
  54.   Trans = (2*OutterRad + InnerRad) * sinoftilt + InnerRad +
  55.           ((1 - sinoftilt) * InnerRad) - (InnerRad * 1/10);
  56.  
  57.   TransCone = Trans + (OutterRad * sinoftilt + InnerRad);
  58. }
  59.  
  60.   /* I used code from the book's accnot.c as a starting point for lighting.
  61.      I have one positional light in center, then one directional */
  62. void myglInit(void)
  63. {
  64.   GLfloat light0_position[] = { 1.0, 0.2, 1.0, 0.0 };
  65.   GLfloat light1_position[] = { 0.0, 0.0, 0.0, 1.0 };
  66.   GLfloat light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
  67.   GLfloat light1_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  68.   GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
  69.  
  70.   glEnable(GL_NORMALIZE);
  71.   glMatrixMode(GL_PROJECTION);
  72.   glLoadIdentity();
  73.   glMatrixMode(GL_MODELVIEW);
  74.   glLoadIdentity();
  75.  
  76.   glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
  77.   glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
  78.   glLightfv(GL_LIGHT1, GL_DIFFUSE,  light1_diffuse);
  79.   glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
  80.   glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.2);
  81.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient);
  82.  
  83.   glEnable(GL_LIGHTING);
  84.   glEnable(GL_LIGHT0);
  85.   glEnable(GL_LIGHT1);
  86.  
  87.   glDepthFunc(GL_LESS);
  88.   glEnable(GL_DEPTH_TEST);
  89.  
  90.   glFlush();
  91.  
  92. void myreshape(GLsizei w, GLsizei h)
  93. {
  94.   glViewport(0,0,w,h);
  95.   glFlush();
  96. }
  97.  
  98.   /* setup display lists to change material for inner/outter rings and
  99.      to draw a single torus or cone */
  100. void MakeDisplayLists(void)
  101. {
  102.   GLfloat cone_diffuse[] = { 0.0, 0.7, 0.7, 1.0 };
  103.   GLfloat mat1_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
  104.   GLfloat mat2_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
  105.   GLfloat torus1_diffuse[] = { 0.7, 0.7, 0.0, 1.0 };
  106.   GLfloat torus2_diffuse[] = { 0.3, 0.0, 0.0, 1.0 };
  107.   GLfloat mat1_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  108.   GLfloat mat2_specular[] = { 0.5, 0.5, 0.5, 1.0 };
  109.  
  110.   glNewList(INNERMAT, GL_COMPILE);
  111.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat1_specular);
  112.     glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
  113.     glMaterialfv(GL_FRONT, GL_DIFFUSE, torus1_diffuse);    
  114.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat1_ambient);
  115.   glEndList();
  116.  
  117.   glNewList(OUTTERMAT, GL_COMPILE);
  118.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat2_specular);
  119.     glMaterialf(GL_FRONT, GL_SHININESS, 25.0);
  120.     glMaterialfv(GL_FRONT, GL_DIFFUSE, torus2_diffuse);    
  121.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat2_ambient);
  122.   glEndList();
  123.  
  124.   glNewList(CONE, GL_COMPILE);
  125.     glMaterialfv(GL_FRONT, GL_DIFFUSE, cone_diffuse);    
  126.     glPushMatrix();
  127.       glTranslatef(0, -TransCone, 0);
  128.       glRotatef(90, 1, 0, 0);
  129.       glutSolidCone(OutterRad, 10, 8, 8);
  130.     glPopMatrix();
  131.   glEndList();
  132.  
  133.   glNewList(TORUS, GL_COMPILE);
  134.     glPushMatrix();
  135.       glRotatef(90, 1, 0, 0);
  136.       glutSolidTorus(InnerRad, OutterRad, 15, 25);
  137.     glPopMatrix();
  138.   glEndList();
  139. }
  140.   
  141.   /* Draw three rings, rotated and translate so they look cool */
  142. void DrawRings(float axis)
  143. {
  144.   GLfloat x = sin(axis), y = cos(axis);
  145.  
  146.   glPushMatrix();
  147.     glTranslatef(0, Trans, 0);
  148.     glRotatef(Tilt, x, 0, y);
  149.     glCallList(TORUS);  
  150.   glPopMatrix();
  151.  
  152.   glPushMatrix();
  153.     glRotatef(-Tilt, x, 0, y);
  154.     glCallList(TORUS);
  155.   glPopMatrix();
  156.  
  157.   glPushMatrix();
  158.     glTranslatef(0, -Trans, 0);
  159.     glRotatef(Tilt, x, 0, y);
  160.     glCallList(TORUS);
  161.   glPopMatrix();
  162. }
  163.  
  164.   /* Draw the inner thing, then glScale and draw 3 huge rings */
  165. void mydisplay(void)
  166. {
  167.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  168.  
  169.   glMatrixMode(GL_PROJECTION);
  170.   glLoadIdentity();
  171.   glFrustum(-1, 1, -1, 1, 10, 1000); 
  172.   gluLookAt(0, 0, Dist, 0, 0, 0, 0, 1, 0);
  173.  
  174.   glMatrixMode(GL_MODELVIEW);
  175.  
  176.   glCallList(INNERMAT);
  177.   DrawRings(Axis);
  178.   glCallList(CONE);
  179.  
  180.   glCallList(OUTTERMAT);
  181.   glPushMatrix();
  182.     glScalef(10, 10, 10);
  183.     DrawRings(Axis/3);
  184.   glPopMatrix();
  185.  
  186.   glutSwapBuffers();
  187.   glFlush();
  188. }
  189.  
  190.   /* rotate the axis and adjust position if nec. */
  191. void myidle(void)
  192.   Axis += AxisInc;
  193.  
  194.   if (Dist < 15 && Fade)    /* start slow */
  195.     Dist += 0.1;
  196.   else if (Dist < 800 && Fade)   /* don't go back too far */
  197.     Dist *= 1.005;  
  198.  
  199.   mydisplay();
  200. }
  201.  
  202.   /* nothing fancy */
  203. void handlemenu(int value)
  204. {
  205.   switch (value) {
  206.     case MENU_STARTOVER:
  207.       Dist = 10; Axis = 0; Fade = 1;
  208.       AxisInc = (2.0 * M_PI / STEPS);
  209.       glutChangeToMenuEntry(3, "Stop rings", MENU_STOP_RINGS);
  210.       glutChangeToMenuEntry(4, "Stop fade", MENU_STOP_FADE);
  211.       break;
  212.     case MENU_ZOOM_OUT:
  213.       Dist = 800;
  214.       break;
  215.     case MENU_STOP_RINGS:
  216.       AxisInc = 0;
  217.       glutChangeToMenuEntry(3, "Start rings", MENU_START_RINGS);
  218.       break;
  219.     case MENU_START_RINGS:
  220.       AxisInc = (2.0 * M_PI / STEPS);
  221.       glutChangeToMenuEntry(3, "Stop rings", MENU_STOP_RINGS);
  222.       break;
  223.     case MENU_STOP_FADE:
  224.       Fade = 0;
  225.       glutChangeToMenuEntry(4, "Start fade", MENU_START_FADE);
  226.       break;
  227.     case MENU_START_FADE:
  228.       Fade = 1;
  229.       glutChangeToMenuEntry(4, "Stop fade", MENU_STOP_FADE);
  230.       break;
  231.     case MENU_QUIT:
  232.       exit(0);
  233.       break;
  234.     }
  235. }
  236.  
  237. void MenuInit(void)
  238. {
  239.   glutCreateMenu(handlemenu);
  240.   glutAddMenuEntry("Start Over", MENU_STARTOVER);
  241.   glutAddMenuEntry("Zoom Out", MENU_ZOOM_OUT);
  242.   glutAddMenuEntry("Stop rings", MENU_STOP_RINGS);
  243.   glutAddMenuEntry("Stop fade", MENU_STOP_FADE);
  244.   glutAddMenuEntry("Quit", MENU_QUIT);
  245.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  246. }
  247.  
  248. void
  249. vis(int visible)
  250. {
  251.   if (visible == GLUT_VISIBLE) {
  252.       glutIdleFunc(myidle);
  253.   } else {
  254.       glutIdleFunc(NULL);
  255.   }
  256. }
  257.  
  258. int main(int argc, char** argv)
  259. {
  260.   glutInit(&argc, argv);
  261.   glutInitWindowSize(512, 512);
  262.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  263.   glutCreateWindow("rings");
  264.  
  265.   myInit();
  266.   myglInit(); 
  267.  
  268.   MakeDisplayLists();
  269.   MenuInit();
  270.  
  271.   glutReshapeFunc(myreshape);
  272.   glutDisplayFunc(mydisplay);
  273.   glutVisibilityFunc(vis);
  274.  
  275.   glutMainLoop();
  276.   return 0;             /* ANSI C requires main to return int. */
  277. }
  278.